← Writeups

JWT authentication bypass via kid header path traversal

This lab uses a JWT-based mechanism for handling sessions. In order to verify the signature, the server uses the kid parameter in JWT header to fetch the relevant key from its filesystem.

To solve the lab, forge a JWT that gives you access to the admin panel at /admin, then delete the user carlos.

You can log in to your own account using the following credentials: wiener:peter


https://siunam321.github.io/ctf/portswigger-labs/JWT/jwt-6/

  • Utiliza un algoritmo de encriptacion simetrica, el ejercicio describe que para verificar la firma, el servidor utiliza el parametro kid en el heade JWT para recuperar o fetch la key del sistema de archivos, es decir este parametro es del sistema de archivos del servidor web, por lo tanto, se podria forzar al servidor a utilizar un archivo arbitrario de su sistema de archivos como clave de verificacion
{
  "kid": "dd8b2c75-ee9a-4955-8d0b-a7b29fa97455",
  "alg": "HS256"
}
{
  "iss": "portswigger",
  "exp": 1757265493,
  "sub": "wiener"
}

para ello maniuplamos el campo kid hacia un archivo estatico predecible, luego firmamos el JWT utilizando un secret que coincida con los contenidos del archivo. Por ejemplo /dev/null es un archivo vacio, entonces recuperarlo, retorna null, en consecuencia, si firmamos el token con null byte codificado en base64 nos retornada una firma valida

printf '\0' | base64

El resultado es

AA==

https://www.youtube.com/watch?v=78FIFrOi4Os Como vamos a firmar el el JWT vamos a tener entonces que crear una clave de encriptacion simetrica, puedes utilizar el plugin JWT Editor para ello. Luego modifica el campo "k" por el null byte codificado en base64 AA== y guardarlo luego regresa a la request en Repeater y presiona en Sign para firmar el JWT el cual tiene el valor kid con un path traversal hacia /dev/null

{  
    "kid": "../../../../../../../../../../dev/null",  
    "alg": "HS256"  
}

A partir de aqui tienes que probar enviando las requests y firmando con cada cambio, revisa tambien la ruta de la GET request que envias que no apunte a la de un usuario como wiener o apunta directamente a /admin o /my-user


Lo que hemos aprendido, repasado:

  • Path traversal mediante JWT para realizar un auth bypass
  • Crear clave privada utilizando JWT Editor para poder firmar un JWT